﻿using System.Globalization;
using ETW;
using RockBus.Logging.Interfaces;
using System;
using System.Reflection;
using System.Transactions;

namespace RockBus.Logging.Etw
{
    public class EtwLogger : ILogger
    {
        public void Log(MethodBase currentMethod, MessageData messageData)
        {
            switch (messageData.LogLevel)
            {
                case LogLevelEnum.Error:
                    RockBusEtwProvider.EventWriteMessageError(
                        messageData.CorrelationId,
                        messageData.Action,
                        messageData.ReceiveAddress,
                        messageData.DestinationAddress,
                        messageData.Text,
                        messageData.MessageEvent.ToString());
                    break;

                case LogLevelEnum.Warning:
                    RockBusEtwProvider.EventWriteMessageWarning(
                        messageData.CorrelationId,
                        messageData.Action,
                        messageData.ReceiveAddress,
                        messageData.DestinationAddress,
                        messageData.Text,
                        messageData.MessageEvent.ToString());
                    break;

                case LogLevelEnum.Info:
                    RockBusEtwProvider.EventWriteMessageInfo(
                        messageData.CorrelationId,
                        messageData.Action,
                        messageData.ReceiveAddress,
                        messageData.DestinationAddress,
                        messageData.Text,
                        messageData.MessageEvent.ToString());
                    break;

                case LogLevelEnum.Debug:
                    RockBusEtwProvider.EventWriteMessageDebug(
                        messageData.CorrelationId,
                        messageData.Action,
                        messageData.ReceiveAddress,
                        messageData.DestinationAddress,
                        messageData.Text,
                        messageData.MessageEvent.ToString());
                    break;

                case LogLevelEnum.Verbose:
                    RockBusEtwProvider.EventWriteMessageVerbose(
                        messageData.CorrelationId,
                        messageData.Action,
                        messageData.ReceiveAddress,
                        messageData.DestinationAddress,
                        messageData.Text,
                        messageData.MessageEvent.ToString());
                    break;

                default:
                    break;
            }
        }

        public void Log(MethodBase currentMethod, LogData logData)
        {
            switch (logData.LogLevel)
            {
                case LogLevelEnum.Error:
                    RockBusEtwProvider.EventWriteLogError(logData.Text);
                    break;

                case LogLevelEnum.Warning:
                    RockBusEtwProvider.EventWriteLogWarning(logData.Text);
                    break;

                case LogLevelEnum.Info:
                    RockBusEtwProvider.EventWriteLogInfo(logData.Text);
                    break;

                case LogLevelEnum.Debug:
                    RockBusEtwProvider.EventWriteLogDebug(logData.Text);
                    break;

                case LogLevelEnum.Verbose:
                    RockBusEtwProvider.EventWriteLogVerbose(logData.Text);
                    break;

                default:
                    break;
            }
        }

        public void Log(MethodBase currentMethod, LogLevelEnum logLevel, string text, params object[] args)
        {
            if ((null != args) && (args.Length > 0))
            {
                text = string.Format(text, args);
            }

            switch (logLevel)
            {
                case LogLevelEnum.Error:
                    RockBusEtwProvider.EventWriteLogError(text);
                    break;

                case LogLevelEnum.Warning:
                    RockBusEtwProvider.EventWriteLogWarning(text);
                    break;

                case LogLevelEnum.Info:
                    RockBusEtwProvider.EventWriteLogInfo(text);
                    break;

                case LogLevelEnum.Debug:
                    RockBusEtwProvider.EventWriteLogDebug(text);
                    break;

                case LogLevelEnum.Verbose:
                    RockBusEtwProvider.EventWriteLogVerbose(text);
                    break;

                default:
                    break;
            }
        }

        public void Log(MethodBase currentMethod, Exception exc)
        {
            this.LogError(currentMethod, exc.ToString());
        }

        public void LogError(MethodBase currentMethod, string text, params object[] args)
        {
            this.Log(currentMethod, LogLevelEnum.Error, text, args);
        }

        public void LogWarning(MethodBase currentMethod, string text, params object[] args)
        {
            this.Log(currentMethod, LogLevelEnum.Warning, text, args);
        }

        public void LogInfo(MethodBase currentMethod, string text, params object[] args)
        {
            this.Log(currentMethod, LogLevelEnum.Info, text, args);
        }

        public void LogDebug(MethodBase currentMethod, string text, params object[] args)
        {
            this.Log(currentMethod, LogLevelEnum.Debug, text, args);
        }

        public void LogVerbose(MethodBase currentMethod, string text, params object[] args)
        {
            this.Log(currentMethod, LogLevelEnum.Verbose, text, args);
        }

        public void Log(MethodBase currentMethod, LogLevelEnum logLevel, Transaction transaction)
        {
            if (null == transaction)
            {
                this.Log(currentMethod, logLevel, "Transaction: None");
            }
            else
            {
                this.Log(currentMethod, logLevel, "{0}, {1}, {2}, {3}",
                    transaction.TransactionInformation.CreationTime.ToString(CultureInfo.CurrentCulture),
                    transaction.TransactionInformation.LocalIdentifier,
                    transaction.TransactionInformation.DistributedIdentifier.ToString(),
                    transaction.TransactionInformation.Status.ToString());
            }
        }
    }
}